package cn.yuanyuan.guide.transformer.domain;

import java.util.ArrayList;
import java.util.List;

import cn.yuanyuan.guide.parser.entity.ASTNode;
import cn.yuanyuan.guide.parser.entity.Node;
import cn.yuanyuan.guide.transformer.entity.Callee;
import cn.yuanyuan.guide.transformer.entity.Expression;

/**
 * @author wuyitao
 * @date 2022/3/27 10:30 PM
 */
public class CallExpressionVisitor implements Visitor{

    @Override
    public void enter(Node node, Node parent) {
        ASTNode astNode = (ASTNode) node;
        // We start creating a new node `CallExpression` with a nested
        // `Identifier`.
        Callee callee = new Callee("Identifier", astNode.getName());
        Expression expression = new Expression("CallExpression", callee, new ArrayList<>());

        // Next we're going to define a new context on the original
        // `CallExpression` node that will reference the `expression`'s arguments
        // so that we can push arguments.
        astNode.setContext(expression.getArguments());

        // Then we're going to check if the parent node is a `CallExpression`.
        // If it is not...
        if (!"CallExpression".equals(parent.getType())) {

            // We're going to wrap our `CallExpression` node with an
            // `ExpressionStatement`. We do this because the top level
            // `CallExpression` in JavaScript are actually statements.
            expression = new Expression("ExpressionStatement", expression);
        }

        // Last, we push our (possibly wrapped) `CallExpression` to the `parent`'s
        // `context`.
        astNode = (ASTNode) parent;
        List<Node> context = astNode.getContext();
        if (context == null) {
            context = new ArrayList<>();
            astNode.setContext(context);
        }
        context.add(expression);
    }

    @Override
    public void exit(Node node, Node parent) {

    }

}
